package com.dormitory.management.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dormitory.management.system.entity.*;
import com.dormitory.management.system.enums.RepairEnum;
import com.dormitory.management.system.enums.UserEnum;
import com.dormitory.management.system.mapper.*;
import com.dormitory.management.system.req.*;
import com.dormitory.management.system.resp.RepairResp;
import com.dormitory.management.system.resp.StuAndHouResp;
import com.dormitory.management.system.service.RepairService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dormitory.management.system.service.UserService;
import com.dormitory.management.system.utils.EmailUtil;
import com.dormitory.managemnet.util.utils.BeanUtil;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 报修表 服务实现类
 * </p>
 *
 * @author
 * @since 2021-12-17
 */
@Service
public class RepairServiceImpl extends ServiceImpl<RepairMapper, Repair> implements RepairService {

    @Autowired
    private UserService userService;
    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private RoomMapper roomMapper;
    @Autowired
    private BuildingMapper buildingMapper;
    @Autowired
    private HousemasterMapper housemasterMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public boolean save(RepairSaveReq req) {
        Student student = studentMapper.selectOne(new QueryWrapper<Student>().lambda().eq(Student::getStuId, req.getStuId()));
        if(student.getRoomId()!=null) {
            if (this.baseMapper.insert(BeanUtil.copyProperties(req, Repair.class)) > 0) {
                //发送邮件
                sendWaitingMail(req.getStuId());
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean delete(Long id) {
        return this.baseMapper.deleteById(id)>0;
    }

    @Override
    public boolean update(RepairUpdateReq req) {
        return this.baseMapper.updateById(BeanUtil.copyProperties(req,Repair.class))>0;
    }

    @Override
    public boolean updateAppeal(RepairAppealReq req) {
        Repair repair = this.baseMapper.selectById(req.getId());
        repair.setAppeal(req.getAppeal());
        repair.setGmtModified(new Date());
        repair.setStatus(RepairEnum.REPAIR_REPORT.getStatusId());
        if(this.baseMapper.updateById(repair)>0){
            //发送邮件
            sendAppealMail(repair.getStuId());
        }
        return false;
    }

    @Override
    public boolean updateStatus(RepairStatusReq req) {
        Repair repair = this.baseMapper.selectById(req.getId());
        if (userService.getRoleKey(req.getUsername()).equals(UserEnum.USER_HOUSEMASTER.getRoleKey())) {
            if(repair.getStatus()!=RepairEnum.REPAIR_END.getStatusId()){
                repair.setStatus(RepairEnum.REPAIR_SOLVE.getStatusId());
                repair.setGmtModified(new Date());
                if(this.baseMapper.updateById(repair) > 0){
                    //发送邮件
                    sendSolveMail(repair.getStuId(),req.getUsername());
                    return true;
                }
                return false;
            }
            return false;
        }else if (userService.getRoleKey(req.getUsername()).equals(UserEnum.USER_STUDENT.getRoleKey())) {
            if(repair.getStatus()!=RepairEnum.REPAIR_END.getStatusId()) {
                repair.setStatus(RepairEnum.REPAIR_END.getStatusId());
                repair.setGmtEnd(new Date());
                if(this.baseMapper.updateById(repair) > 0){
                    //发送邮件
                    sendEndMail(req.getUsername());
                    return true;
                }
                return false;
            }
            return false;
        }else
            return true;
    }

    @Override
    public IPage<RepairResp> getPage(RepairPageReq req) {
        if (userService.getRoleKey(req.getUsername()).equals(UserEnum.USER_HOUSEMASTER.getRoleKey())) {
            return this.baseMapper.getRepairPage(new Page<>(req.getPageCurrent(),req.getPageSize()),new QueryWrapper<RepairResp>()
                    .eq("identity_card",req.getUsername())
                    .eq(req.getTypeId()!=null,"type_id",req.getTypeId())
                    .eq("r.status_id",0)
                    .eq("s.status_id",0)
                    .eq("h.status_id",0)
                    .like(req.getRoom()!=null,"room.room",req.getRoom())
                    .like(req.getStuId()!=null,"r.stu_id",req.getStuId())
                    .like(req.getStatus()!=null,"r.status",req.getStatus())
                    .apply(req.getGmtStart()!=null,"TO_DAYS(r.gmt_create) >= TO_DAYS('"+ DateFormatUtils.format(req.getGmtStart(), "yyyy-MM-dd HH:mm:ss")+"')")
                    .apply(req.getGmtEnd()!=null,"TO_DAYS(r.gmt_create) <= TO_DAYS('"+ DateFormatUtils.format(req.getGmtEnd(), "yyyy-MM-dd HH:mm:ss")+"')")
//                    .ge(req.getGmtStart()!=null,"r.gmt_create",req.getGmtStart())
//                    .le(req.getGmtEnd()!=null,"r.gmt_create",req.getGmtEnd())
                    .orderByAsc("r.status"));
        }else if (userService.getRoleKey(req.getUsername()).equals(UserEnum.USER_STUDENT.getRoleKey())) {
            Student student = studentMapper.selectOne(new QueryWrapper<Student>().lambda().eq(Student::getStuId,req.getUsername()));
            return this.baseMapper.getRepairStuPage(new Page<>(req.getPageCurrent(),req.getPageSize()),new QueryWrapper<RepairResp>()
                    .eq("room_id",student.getRoomId())
                    .eq("r.status_id",0)
                    .eq("s.status_id",0)
                    .orderByAsc("r.status"));
        }else
            return this.baseMapper.getRepairStuPage(new Page<>(req.getPageCurrent(),req.getPageSize()),new QueryWrapper<RepairResp>()
                    .eq("r.status_id",0)
                    .eq("s.status_id",0)
                    .orderByAsc("r.status"));
    }

    //学生维修上报后发送
    private void sendWaitingMail(String stuId){
        StuAndHouResp studentInfo = studentMapper.getStudentInfo(new QueryWrapper<StuAndHouResp>().eq("s.stu_id", stuId));
        Room roomStu = roomMapper.selectById(studentInfo.getRoomId());
        List<Housemaster> housemasters = housemasterMapper.selectList(new QueryWrapper<Housemaster>().lambda().eq(Housemaster::getBuildingId, roomStu.getBuildingId()));
        for (Housemaster housemaster : housemasters) {
            Email email = new Email(studentInfo.getPhone(),studentInfo.getName(),userService.getRoleKey(stuId));
            String emailHou = housemaster.getEmail();
            String name = housemaster.getName();
            String room=studentInfo.getLiving()+"-"+studentInfo.getBuilding()+"-"+studentInfo.getRoom();
            String content = email.repairWaiting(name, room);
            String subject="新的维修报单已发布请查收";
            String filePath=null;
            redisTemplate.opsForValue().set(emailHou+"***"+subject+"***"+content+"***"+filePath,"dxc",10, TimeUnit.SECONDS);
        }
    }

    //学生维修申报后发送
    private void sendAppealMail(String stuId){
        StuAndHouResp studentInfo = studentMapper.getStudentInfo(new QueryWrapper<StuAndHouResp>().eq("s.stu_id", stuId));
        Room roomStu = roomMapper.selectById(studentInfo.getRoomId());
        List<Housemaster> housemasters = housemasterMapper.selectList(new QueryWrapper<Housemaster>().lambda().eq(Housemaster::getBuildingId, roomStu.getBuildingId()));
        for (Housemaster housemaster : housemasters) {
            Email email = new Email(studentInfo.getPhone(),studentInfo.getName(),userService.getRoleKey(stuId));
            String emailHou = housemaster.getEmail();
            String name = housemaster.getName();
            String room=studentInfo.getLiving()+"-"+studentInfo.getBuilding()+"-"+studentInfo.getRoom();
            String content = email.repairAppeal(name, room);
            String subject="新的维修申报已更新请查收";
            String filePath=null;
            redisTemplate.opsForValue().set(emailHou+"***"+subject+"***"+content+"***"+filePath,"dxc",10,TimeUnit.SECONDS);
        }
    }

    //宿管更新维修状态后发送
    private void sendSolveMail(String stuId,String username){
        StuAndHouResp studentInfo = studentMapper.getStudentInfo(new QueryWrapper<StuAndHouResp>().eq("s.stu_id", stuId));
        StuAndHouResp userInfo = userService.getUserInfo(username);
        Email email = new Email(userInfo.getPhone(),userInfo.getName(),userService.getRoleKey(username));
        String emailHou = studentInfo.getEmail();
        String name = studentInfo.getName();
        String room=studentInfo.getLiving()+"-"+studentInfo.getBuilding()+"-"+studentInfo.getRoom();
        String content = email.repairSolve(name, room);
        String subject="维修已完成请查收";
        String filePath=null;
        redisTemplate.opsForValue().set(emailHou+"***"+subject+"***"+content+"***"+filePath,"dxc",10,TimeUnit.SECONDS);

    }

    //学生维修完结后发送
    private void sendEndMail(String username){
        StuAndHouResp studentInfo = studentMapper.getStudentInfo(new QueryWrapper<StuAndHouResp>().eq("s.stu_id", username));
        Room roomStu = roomMapper.selectById(studentInfo.getRoomId());
        List<Housemaster> housemasters = housemasterMapper.selectList(new QueryWrapper<Housemaster>().lambda().eq(Housemaster::getBuildingId, roomStu.getBuildingId()));
        for (Housemaster housemaster : housemasters) {
            Email email = new Email("13958876486", "工作人员", "行政部");
            String emailHou = housemaster.getEmail();
            String name = housemaster.getName();
            String room = studentInfo.getLiving() + "-" + studentInfo.getBuilding() + "-" + studentInfo.getRoom();
            String content = email.repairEnd(name, room);
            String subject = "维修已完结";
            String filePath = null;
            redisTemplate.opsForValue().set(emailHou+"***"+subject+"***"+content+"***"+filePath,"dxc",10,TimeUnit.SECONDS);
        }

    }


}
